<template>
    <div style="user-select: text" >
      <div class="tools-box">
        <div class="tools-box-item">
          <el-button link @click="addTableRow">
            <el-icon size="18" color="#b88230">
              <CirclePlus/>
            </el-icon>
            <span style="font-size: 14px;">添加记录</span>
          </el-button>
        </div>
        <div class="tools-box-item">
          <el-button link @click="editTableRow">
            <el-icon size="18" color="#337ecc">
              <Edit/>
            </el-icon>
            <span style="font-size: 14px;">修改记录</span>
          </el-button>
        </div>
        <div class="tools-box-item">
          <el-button link @click="deleteTableRow">
            <el-icon size="18" color="#c45656">
              <Remove/>
            </el-icon>
            <span style="font-size: 14px;">删除记录</span>
          </el-button>
        </div>
        <div class="tools-box-item">
          <el-button   :link="showSqlBox!=='text'" @click="showSqlBoxStatus('text')">
            <el-icon size="18" color="#73767a">
              <Document/>
            </el-icon>
            <span style="font-size: 14px;">文本</span>
          </el-button>
        </div>
        <div class="tools-box-item">
          <el-button :link="showSqlBox!=='where'" @click="showSqlBoxStatus('where')">
            <el-icon size="18" color="#73767a">
              <Filter/>
            </el-icon>
            <span style="font-size: 14px;">筛选</span>
          </el-button>
        </div>
        <div class="tools-box-item">
          <el-button :link="showSqlBox!=='order'" @click="showSqlBoxStatus('order')">
            <el-icon size="18" color="#73767a">
              <Sort/>
            </el-icon>
            <span style="font-size: 14px;">排序</span>
          </el-button>
        </div>
        <div class="tools-box-item">
          <el-button link @click="pageChange">
            <el-icon size="18" color="#73767a">
              <Refresh/>
            </el-icon>
            <span style="font-size: 14px;">重新加载</span>
          </el-button>
        </div>
      </div>
      <div class="table-box">
        <div class="show-sql-box"  v-show="showSqlBox==='where'">
          <el-scrollbar>
            <div class="show-sql-box-item" >
              <div class="show-sql-box-item-row" v-for="(row,rowIndex) in showSqlBoxWhere">
                <el-select  v-model="row.field"  size="small" style="width:120px;">
                  <el-option   v-for="field in fieldList" :key="field.COLUMN_NAME"  :label="field.COLUMN_NAME" :value="field.COLUMN_NAME" />
                </el-select>
                <el-select  v-model="row.symbol" size="small" style="margin: 0px 10px;width:120px;">
                  <el-option   v-for="(symbol,index) in symbolList" :key="index"  :label="symbol.label" :value="symbol.value" />
                </el-select>
                <el-input v-model="row.fieldValue" size="small" style="width:120px;" />
                <el-input v-model="row.secondFieldValue" size="small" style="width:120px;margin-left: 5px;" v-if="row.symbol.includes('between')"/>
                <el-select  v-model="row.constructorType" size="small" style="margin: 0px 10px;width:120px;" v-if="row.constructorType">
                  <el-option   v-for="(connectorType,index) in connectorList" :key="index"  :label="connectorType.label" :value="connectorType.value" />
                </el-select>
                <el-button style="margin-left: 10px" type="danger"  size="small" icon="Delete" @click="deleteSqlWhereRow(rowIndex)" />
              </div>
              <div class="show-sql-box-item-row" style="width: 100%;margin-top: 10px;">
                <el-button type="primary" size="small" icon="Plus"   @click="addSqlWhereRow" />
                <el-button style="margin-left: 10px" type="success"  size="small" icon="Search" @click="querySql" />
                <el-button style="margin-left: 10px" type="danger"  size="small"  @click="clearAllWhere" >清除全部</el-button>
              </div>
            </div>
          </el-scrollbar>
        </div>
        <div class="show-sql-box"  v-show="showSqlBox==='order'">
          <el-scrollbar>
            <div class="show-sql-box-item" >
              <div class="show-sql-box-item-row" v-for="(orderData,orderIndex) in showSqlBoxOrder" >
                <el-select     v-model="orderData.orderField"  size="small" style="width:120px;" >
                  <el-option   v-for="field in fieldList" :key="field.COLUMN_NAME"  :label="field.COLUMN_NAME" :value="field.COLUMN_NAME" />
                </el-select>
                <el-select     v-model="orderData.orderType" size="small" style="width:120px;margin-left: 10px;">
                  <el-option   v-for="(orderType,index) in orderTypeList" :key="index"  :label="orderType.label" :value="orderType.value" />
                </el-select>
                <el-button style="margin-left: 10px" type="danger"  size="small" icon="Delete"  @click="deleteSqlOrderRow(orderIndex)" />
              </div>
              <div  class="show-sql-box-item-row" style="width: 100%;margin-top: 10px;">
                <el-button type="primary" size="small" icon="Plus"    @click="addSqlOrderRow" />
                <el-button style="margin-left: 10px" type="success"  size="small" icon="Search" @click="querySql" />
                <el-button style="margin-left: 10px" type="danger"  size="small"  @click="clearAllOrder" >清除全部</el-button>
              </div>
            </div>
          </el-scrollbar>
        </div>
        <el-table :data="dataList" border  v-loading="loading" :height="showSqlBox?'calc(100vh - 320px)':'calc(100vh - 200px)'" highlight-current-row @row-click="tableClickRow" @cell-click="tableClickCell">
          <el-table-column type="index" width="50" fixed >
            <template #default="scope">
              <div style="width: 100%;display: flex;justify-content: flex-start;">
                <div v-if="selectRowIndex===(scope.$index+1)"><el-icon size="18"><CaretRight /></el-icon></div>
                <div>{{initIndex(scope.$index)}}</div>
              </div>
            </template>
          </el-table-column>
          <el-table-column :key="field.COLUMN_NAME" :label="field.COLUMN_NAME"
                           :min-width="getColumnWidth(field.COLUMN_NAME)" :prop="field.COLUMN_NAME" show-overflow-tooltip
                           v-for="field in fieldList">
            <template #default="scope">
              {{getDateFormat(field,scope.row[field.COLUMN_NAME])}}
            </template>
          </el-table-column>
        </el-table>
        <div class="show-sql-box"  v-show="showSqlBox==='text'">
          <el-scrollbar>
            <div  style="text-align: left;margin: 10px;" >
              {{bigText}}
            </div>
          </el-scrollbar>
        </div>
        <div class="bottom-tools">
          <el-scrollbar>
            <div class="sql-box">
              <div class="sql-box-item" v-if="selectRowIndex>0"> 第{{selectRowIndex}}条记录</div>
              <div class="sql-box-item">（共{{dataParams.total}}条）</div>
              <div class="sql-box-item">SELECT * FROM </div>
              <div class="sql-box-item"> {{ `${dataParams.databaseName}.${dataParams.tableKey}`}}</div>
              <div class="sql-box-item" v-if="sqlWhere"> {{sqlWhere}}</div>
              <div class="sql-box-item"> {{`LIMIT ${(dataParams.pageNumber-1)*dataParams.pageSize},${dataParams.pageSize}`}}</div>
            </div>
          </el-scrollbar>
          <div>
            <el-pagination background layout="prev,pager, next, jumper" small
                           :total="dataParams.total"
                           :default-current-page="dataParams.pageNumber"
                           :default-page-size="dataParams.pageSize"
                           @change="pageChange" v-model:page-size="dataParams.pageSize"
                           v-model:current-page="dataParams.pageNumber"/>
          </div>
        </div>
      </div>
      <div>
        <el-dialog v-model="openDialog" v-if="openDialog" :width="fieldList.length>10?'65vw':'400px'" :show-close="false" modal :close-on-click-modal="false" :close-on-press-escape="false">
          <div class="drawTitle">
            <div style="margin-left:5px">{{ `${isEdit ? '编辑数据' : '添加数据'}` }}({{ dataParams.tableKey }})</div>
          </div>
          <div>
            <el-scrollbar max-height="400px">
              <el-form :model="tableForm" :inline="fieldList.length>10" label-position="top" label-width="auto" size="small"  >
                <el-form-item :label="field.COLUMN_NAME" v-for="field in fieldList" >
                  <div style="display: flex;justify-content: flex-start">
                    <div>
                      <el-input-number   v-model="tableForm[field.COLUMN_NAME]"  style="width: 220px"  :controls="false" :input-style="{'text-align': 'left'}"           v-if="checkNumber(field.DATA_TYPE)" />
                      <el-date-picker    v-model="tableForm[field.COLUMN_NAME]"  style="width: 220px"  type="date"       format="YYYY-MM-DD" value-format="YYYY-MM-DD"  v-else-if="field.DATA_TYPE==='date'" />
                      <el-date-picker    v-model="tableForm[field.COLUMN_NAME]"  style="width: 220px"  type="datetime"   format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss"   v-else-if="field.DATA_TYPE==='timestamp'||field.DATA_TYPE==='datetime'" />
                      <el-date-picker    v-model="tableForm[field.COLUMN_NAME]"  style="width: 220px"  type="year"       v-else-if="field.DATA_TYPE==='year'" />
                      <el-time-picker    v-model="tableForm[field.COLUMN_NAME]"  style="width: 220px"  arrow-control     format="HH:mm:ss" value-format="HH:mm:ss"     v-else-if="field.DATA_TYPE==='time'" />
                      <el-input          v-model="tableForm[field.COLUMN_NAME]"  style="width: 220px"  v-else-if="field.CHARACTER_MAXIMUM_LENGTH&&field.CHARACTER_MAXIMUM_LENGTH<50"/>
                      <el-input          v-model="tableForm[field.COLUMN_NAME]"  style="width: 220px"  type="textarea" v-else/>
                    </div>
                    <div style="margin-left: 10px;">
                      <el-tooltip  class="box-item" effect="dark" :content="field.COLUMN_COMMENT" placement="top" >
                        <span>备注<el-icon size="12px"><QuestionFilled /></el-icon></span>
                      </el-tooltip>
                    </div>
                  </div>
                </el-form-item>
              </el-form>
            </el-scrollbar>
          </div>
          <template #footer>
            <div class="dialog-footer">
              <el-button @click="openDialog = false">取消</el-button>
              <el-button type="primary" @click="submitData">提交</el-button>
            </div>
          </template>
        </el-dialog>
      </div>
    </div>
</template>

<script setup name="MysqlTableInfoView">
    import {queryTableDataPageList} from '@/utils/connectManager';
    import {formatDate,formatTime} from "@/utils/dateUtils";

    const {proxy} = getCurrentInstance();
    const tableData = reactive({
        dataList: [],
        fieldList: [],
        routeQuery: {},
        loading: false,
        dataParams: {
            pageSize: 100,
            pageNumber: 1,
            tableKey: null,
            databaseName: null,
            total: 0,
        },
        tableCount: 0,
        selectRowIndex:0,
        sqlWhere:null,
        selectRow: {},
        openDialog:false,
        tableForm:{},
        isEdit:false,
        showSqlBox:null,
        showSqlBoxWhere:[],
        showSqlBoxOrder:[],
        symbolList: [
        {'label': '等于', 'value': '='},
        {'label': '不等于', 'value': '!='},
        {'label': '大于', 'value': '>'},
        {'label': '小于', 'value': '<'},
        {'label': '大于等于', 'value': '>='},
        {'label': '小于等于', 'value': '<='},
        {'label': '包含', 'value': 'likeAll'},
        {'label': '不包含', 'value': 'notLikeAll'},
        {'label': '包含左侧', 'value': 'likeLeft'},
        {'label': '包含右侧', 'value': 'likeRight'},
        {'label': '不包含左侧', 'value': 'notLikeLeft'},
        {'label': '不包含右侧', 'value': 'notLikeRight'},
        {'label': '是null', 'value': 'isNull'},
        {'label': '不是null', 'value': 'isNotNull'},
        {'label': '是空', 'value': 'isEmpty'},
        {'label': '不是空', 'value': 'isNotEmpty'},
        {'label': '介于', 'value': 'between'},
        {'label': '不介于', 'value': 'notBetween'},
        {'label': '在列表', 'value': 'in'},
        {'label': '不在列表', 'value': 'notIn'},
      ],
        orderTypeList:[
        {'label':'ASC','value':'ASC'},
        {'label':'DESC','value':'DESC'},
      ],
        connectorList:[
        {'label':'AND','value':'AND'},
        {'label':'OR','value':'OR'},
      ],bigText:null,
    })
    const {dataList, fieldList, routeQuery, loading, dataParams, tableCount,selectRowIndex,sqlWhere,selectRow,openDialog,tableForm,isEdit,showSqlBox,showSqlBoxWhere,showSqlBoxOrder,symbolList,orderTypeList,connectorList,bigText} = toRefs(tableData)
    routeQuery.value = proxy.$route.query
    const connect = ref(null)
    connect.value = proxy.$appStore.connectList.find(row => row.id == (routeQuery.value.connectId * 1))

    function initIndex(index) {
        let rowIndex = index + 1
        if(tableCount.value===0){
          loading.value = false
        }else if(rowIndex===tableCount.value){
          loading.value = false
        }
        return rowIndex;
    }

    function getTableDataList() {
        loading.value = true
        dataParams.value.tableKey = routeQuery.value.tableName
        dataParams.value.databaseName = routeQuery.value.databaseName
        queryTableDataPageList(proxy, connect.value, dataParams.value).then(res => {
            if (res.code === 200) {
                dataParams.value.total = res.total
                dataList.value = res.data.dataList
                fieldList.value=res.data.fieldList
                tableCount.value = dataList.value.length
                if(dataParams.value.total<1){
                  loading.value = false
                }
            } else {
                proxy.$modal.alertError(res.message)
            }
        })
    }


    function getColumnWidth(columnText) {
        if (columnText.length > 20) {
            return 180;
        }
        if (columnText.length > 10) {
            return 160;
        }
        if (columnText.length > 5) {
            return 120;
        }
        return 80;
    }

    function pageChange() {
        tableCount.value=0
        loading.value = true
        getTableDataList()
    }

    function tableClickRow(row,column,event){
      selectRowIndex.value=(dataList.value.indexOf(row)+1)
      selectRow.value=row
    }

    function getDateFormat(field,fieldValue){
      if(field.DATA_TYPE==='datetime'||field.DATA_TYPE==='timestamp'){
        return formatTime(fieldValue);
      }
      if(field.DATA_TYPE==='date'){
        return formatDate(fieldValue);
      }
      return fieldValue;
    }


    const handleEvent = async (event) => {
      if(event.keyCode === 38) {
        //上
        if(selectRowIndex.value>1) {
          selectRowIndex.value = selectRowIndex.value - 1
          selectRow.value=tableData[selectRowIndex.value-1]
        }
      }

      if(event.keyCode === 40) {
        //下
        if(selectRowIndex.value < tableCount.value) {
          selectRowIndex.value = selectRowIndex.value + 1
          selectRow.value=tableData[selectRowIndex.value-1]
        }
      }
    }

    onMounted(() => {
      window.addEventListener('keydown', handleEvent)
    });

    onUnmounted(() => {
      window.removeEventListener('keydown', handleEvent)
    });

    function updateValue(fields,form){
      fields.forEach(item=>{
        if(item.DATA_TYPE==='date'){
          form[item.COLUMN_NAME]=formatDate(form[item.COLUMN_NAME])
        }else if(item.DATA_TYPE==='datetime'||item.DATA_TYPE==='timestamp'){
          form[item.COLUMN_NAME]=formatTime(form[item.COLUMN_NAME])
        }else if(item.DATA_TYPE==='year'){
          form[item.COLUMN_NAME]=form[item.COLUMN_NAME]+''
        }
      })
    }

    function addTableRow(){
      tableForm.value={}
      openDialog.value=true
      isEdit.value=false
    }

    function editTableRow(){
      if(!selectRow.value||selectRowIndex.value<1){
        proxy.$modal.msgWarning('请选择一条要修改的数据！');
        return
      }
      updateValue(fieldList.value,selectRow.value)
      tableForm.value=JSON.parse(JSON.stringify(selectRow.value))
      updateValue(fieldList.value,tableForm.value)
      openDialog.value=true
      isEdit.value=true
    }

    function deleteTableRow(){
      if(!selectRow.value||selectRowIndex.value<1){
        proxy.$modal.msgWarning('请选择一条要修改的数据！');
        return
      }
      proxy.$modal.confirm('是否确认删除当前数据？').then(function() {
        let params=dataParams.value
        updateValue(fieldList.value,selectRow.value)
        params.selectRow=selectRow.value
        return proxy.$userIpc.invoke(proxy.$ipcRouters.mysqlMng.deleteTableRow, connect.value,dataParams.value);
      }).then(() => {
        pageChange()
        proxy.$modal.msgSuccess("删除成功");
      }).catch(() => {});
    }

    function checkNumber(type){
      let localType=type.toLowerCase()
      if(localType==='tinyint'||localType==='smallint'||localType==='mediumint'||localType==='int'||localType==='integer'||localType==='bigint'||localType==='float'||localType==='double'||localType==='decimal'){
        return true
      }
      return false
    }

    function  submitData(){
      proxy.$modal.confirm('是否确认提交当前数据？').then(function() {
        let params=dataParams.value
        updateValue(fieldList.value,selectRow.value)
        params.selectRow=selectRow.value
        params.tableForm=tableForm.value
        if(isEdit.value){
          return proxy.$userIpc.invoke(proxy.$ipcRouters.mysqlMng.editTableRow, connect.value,dataParams.value);
        }else{
          return proxy.$userIpc.invoke(proxy.$ipcRouters.mysqlMng.addTableRow, connect.value,dataParams.value);
        }
      }).then(() => {
        openDialog.value=false
        pageChange()
        proxy.$modal.msgSuccess("提交成功");
      }).catch(() => {});
    }

    function showSqlBoxStatus(showBox){
      sqlWhere.value=null
      if(showSqlBox.value===showBox){
        showSqlBox.value=null
       if(showBox==='text'){
         bigText.value=null
       }
      }else{
        showSqlBox.value=showBox
      }
      dataParams.value.sqlWhere=[]
      dataParams.value.sqlOrder=[]
    }

    function addSqlWhereRow(){
      let row={}
      row.field=fieldList.value[0].COLUMN_NAME
      row.symbol='='
      row.fieldValue=''
      row.secondFieldValue=null
      row.constructorType=null
      showSqlBoxWhere.value.push(row)
      if(showSqlBoxWhere.value.length>1){
        showSqlBoxWhere.value[showSqlBoxWhere.value.length-2].constructorType='AND'
      }else {
        showSqlBoxWhere.value[0].constructorType=null
      }
    }

    function deleteSqlWhereRow(index){
      showSqlBoxWhere.value.splice(index,1);
      if(showSqlBoxWhere.value&&showSqlBoxWhere.value.length>0){
        if(showSqlBoxWhere.value.length===1){
          showSqlBoxWhere.value[0].constructorType=null
        }else {
          showSqlBoxWhere.value[showSqlBoxWhere.value.length-1].constructorType=null
        }
      }
    }

    function addSqlOrderRow(){
      let row={}
      row.orderField=fieldList.value[0].COLUMN_NAME
      row.orderType='ASC'
      showSqlBoxOrder.value.push(row)
    }

    function deleteSqlOrderRow(index){
      showSqlBoxOrder.value.splice(index,1);
    }

    function querySql(){
      let whereSql=''
      showSqlBoxWhere.value.forEach(row=>{
          whereSql=whereSql+"`"+row.field+"`"
        if(row.symbol==='likeAll'){
          whereSql=whereSql+" LIKE '%"+row.fieldValue+"%'"
        }else if(row.symbol==='notLikeAll'){
          whereSql=whereSql+" NOT LIKE '%"+row.fieldValue+"%'"
        }else if(row.symbol==='likeLeft'){
          whereSql=whereSql+" LIKE '%"+row.fieldValue+"'"
        }else if(row.symbol==='likeRight'){
          whereSql=whereSql+" LIKE '"+row.fieldValue+"%'"
        }else if(row.symbol==='notLikeLeft'){
          whereSql=whereSql+" NOT LIKE '%"+row.fieldValue+"'"
        }else if(row.symbol==='notLikeRight'){
          whereSql=whereSql+" NOT LIKE '"+row.fieldValue+"%'"
        }else if(row.symbol==='isNull'){
          whereSql=whereSql+' IS NULL'
        }else if(row.symbol==='isNotNull'){
          whereSql=whereSql+' IS NOT NULL'
        }else if(row.symbol==='isEmpty'){
          whereSql=whereSql+"=''"
        }else if(row.symbol==='isNotEmpty'){
          whereSql=whereSql+"!=''"
        }else if(row.symbol==='between'){
          whereSql=whereSql+" BETWEEN '"+row.fieldValue+"' AND '"+row.secondFieldValue+"'"
        }else if(row.symbol==='notBetween'){
          whereSql=whereSql+" NOT BETWEEN '"+row.fieldValue+"' AND '"+row.secondFieldValue+"'"
        }else if(row.symbol==='in'){
          whereSql=whereSql+" IN ("+row.fieldValue+")"
        }else if(row.symbol==='notIn'){
          whereSql=whereSql+" NOT IN ("+row.fieldValue+")"
        }else {
          whereSql=whereSql+row.symbol+"'"+row.fieldValue+"'"
        }
        if(row.constructorType){
          whereSql=`${whereSql}  ${row.constructorType}`
        }
      })

      if(showSqlBoxWhere.value&&showSqlBoxWhere.value.length>0){
        whereSql = `WHERE  ${whereSql}   `
      }
      let orderArray=[]
      showSqlBoxOrder.value.forEach(row=>{
        let orderItem=" `"+row.orderField+"`"
        if(row.orderType==='DESC'){
          orderItem=`${orderItem} DESC`
        }
        orderArray.push(orderItem)
      })
      if(orderArray.length>0){
        whereSql=`${whereSql}  ORDER BY  ${orderArray.join(',')}`
      }
      sqlWhere.value=whereSql
      dataParams.value.pageNumber=1
      dataParams.value.sqlWhere=showSqlBoxWhere.value
      dataParams.value.sqlOrder=showSqlBoxOrder.value
      pageChange();
    }

    function clearAllOrder(){
      showSqlBoxOrder.value=[]
      dataParams.value.sqlWhere=[]
      dataParams.value.sqlOrder=[]
    }

    function clearAllWhere(){
      showSqlBoxWhere.value=[]
      dataParams.value.sqlWhere=[]
      dataParams.value.sqlOrder=[]
    }

    function tableClickCell(row,column,cell,event){
      if(showSqlBox.value==='text'){
        bigText.value=formatTime(row[column.property])
      }
    }

    getTableDataList()

</script>

<style scoped lang="scss">
.table-box {
  width: 100%;
  font-size: 12px;
}

.tools-box{
  width: 100%;
  height: 36px;
  line-height: 36px;
  display: flex;
  justify-content: flex-start;
  &-item{
    padding: 0 10px;
  }
}

.sql-box{
  display: flex;
  justify-content:flex-start;
  line-height: 32px;
  width: 60vw;
  &-item{
    margin-right: 10px;
  }
}

.bottom-tools{
  display: flex;
  justify-content: space-between;
  line-height: 32px;
}

:deep(.el-input-number .el-input__inner) {
  text-align: left;
  font-size: 14px;
}

:deep(.el-input-number.is-without-controls .el-input__wrapper) {
  padding-left: 10px;
}

:deep(.el-table) {
  --el-table-row-hover-bg-color: transparent;
  --el-table-header-bg-color: transparent;
  --el-table-header-text-color: #303133;
}

:deep(.el-table thead th) {
  font-weight: normal;
}
.show-sql-box{
  width: 99%;
  height: 120px;
  border: 1px solid #D4D7DE;
  display: flex;
  justify-content: flex-start;
  &-item{
    padding-left: 10px;
    padding-top: 10px;
    display: flex;
    flex-wrap: wrap;
    &-row{
      display: flex;
      justify-content: flex-start;
      margin-top: 5px;
      margin-right: 10px;
    }
  }
}
</style>
